package org.ruoyi.common.dhuman.utils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 将PPT或PDF文件转换为单页图片，然后合并为一个大视频
 */
public class DocumentToImagesUtils {

	private static final int DEFAULT_WIDTH = 1920;
	private static final int DEFAULT_HEIGHT = 1080;
	private static final int DEFAULT_FPS = 30;
	private static final int DEFAULT_DURATION_PER_SLIDE = 3; // 每页显示秒数

	/**
	 * 提取文档页面为图片
	 *
	 * @param inputFile 输入文件
	 * @return 页面图片列表
	 * @throws Exception 提取过程中的异常
	 */
	public static List<BufferedImage> extractPagesAsImages(File inputFile) throws Exception {
		String fileName = inputFile.getName().toLowerCase();
		if (fileName.endsWith(".pdf")) {
			return extractPdfPages(inputFile);
		} else if (fileName.endsWith(".pptx")) {
			return extractPptPages(inputFile);
		} else {
			throw new IllegalArgumentException("不支持的文件格式: " + fileName);
		}
	}

	/**
	 * 提取PDF页面为图片
	 *
	 * @param pdfFile PDF文件
	 * @return 页面图片列表
	 * @throws IOException IO异常
	 */
	public static List<BufferedImage> extractPdfPages(File pdfFile) throws IOException {
		List<BufferedImage> images = new ArrayList<>();
		PDDocument document = PDDocument.load(pdfFile);
		PDFRenderer pdfRenderer = new PDFRenderer(document);

		for (int page = 0; page < document.getNumberOfPages(); page++) {
			BufferedImage image = pdfRenderer.renderImageWithDPI(page, 300);
			images.add(resizeImage(image));
		}

		document.close();
		return images;
	}

	/**
	 * 提取PPT页面为图片
	 *
	 * @param pptFile PPT文件
	 * @return 页面图片列表
	 * @throws IOException IO异常
	 */
	public static List<BufferedImage> extractPptPages(File pptFile) throws IOException {
		List<BufferedImage> images = new ArrayList<>();
		// 使用 FileInputStream 替代直接传入 File 对象
		try (java.io.FileInputStream fis = new java.io.FileInputStream(pptFile)) {
			XMLSlideShow ppt = new XMLSlideShow(fis);

			for (XSLFSlide slide : ppt.getSlides()) {
				Dimension bounds = slide.getSlideShow().getPageSize();
				// 提高图片分辨率，使用更高的DPI
				int width = (int) (bounds.getWidth() * 2);
				int height = (int) (bounds.getHeight() * 2);
				BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
				Graphics2D graphics = image.createGraphics();

				// 设置高质量渲染提示
				graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
				graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
				graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);

				// 设置背景为白色，确保全尺寸填充
				graphics.setColor(Color.WHITE);
				graphics.fillRect(0, 0, width, height);

				// 缩放图形以适应高分辨率
				graphics.scale(2.0, 2.0);

				// 绘制幻灯片内容
				slide.draw(graphics);
				graphics.dispose();

				images.add(image);
			}

			return images;
		}
	}

	/**
	 * 调整图片大小
	 *
	 * @param originalImage 原始图片
	 * @return 调整后的图片
	 */
	private static BufferedImage resizeImage(BufferedImage originalImage) {
		int targetWidth = originalImage.getWidth();
		int targetHeight = originalImage.getHeight();
		BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = resizedImage.createGraphics();
		g.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
		g.dispose();
		return resizedImage;
	}

	/**
	 * 将图片列表保存到磁盘
	 *
	 * @param images         图片列表
	 * @param sourceFileName 源文件名，用于创建文件夹
	 * @throws IOException IO异常
	 */
	public static List<File> saveImagesToDisk(String path, List<BufferedImage> images, String sourceFileName) throws IOException {
		// 创建以源文件名命名的文件夹
		String folderName = sourceFileName.substring(0, sourceFileName.lastIndexOf('.'));
		File imageDir = new File(path + "\\" + folderName + "_images");
		if (!imageDir.exists()) {
			imageDir.mkdirs();
		}

		List<File> retList = new ArrayList<File>();
		// 保存每张图片
		for (int i = 0; i < images.size(); i++) {
			File imageFile = new File(imageDir, "slide_" + String.format("%03d", i + 1) + ".png");
			ImageIO.write(images.get(i), "png", imageFile);
			retList.add(imageFile);
		}

		return retList;
	}

}
